package com.xrui.hbaseview.export;

import com.google.common.base.CharMatcher;

import com.univocity.parsers.csv.CsvFormat;
import com.univocity.parsers.csv.CsvWriter;
import com.univocity.parsers.csv.CsvWriterSettings;
import com.xrui.hbaseview.data.DataCell;
import com.xrui.hbaseview.data.DataRow;
import com.xrui.hbaseview.data.TypedColumn;

import java.io.Closeable;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * This class represents an exporter that saves the data into the file.
 */
public class FileExporter implements Exporter, Closeable {
    //region Variables
    private final CsvWriter writer;
    //endregion

    //region Constructor

    /**
     * Initializes a new instance of the {@link FileExporter} class.
     *
     * @param stream    An output stream to write to.
     * @param delimiter A character to be used as a data delimiter.
     */
    public FileExporter(OutputStream stream, char delimiter) {
        CsvWriterSettings settings = new CsvWriterSettings();
        CsvFormat csvFormat = new CsvFormat();
        csvFormat.setDelimiter(delimiter);
        settings.setHeaderWritingEnabled(true);
        settings.setFormat(csvFormat);
        this.writer = new CsvWriter(stream, StandardCharsets.UTF_8, settings);
    }
    //endregion

    //region Public Methods

    /**
     * Writes a list of rows to the output stream.
     *
     * @param row A row to write.
     * @throws IOException when error
     */
    @Override
    public void write(DataRow row, Iterable<TypedColumn> columns) throws IOException {
        Map<String, String> fields = new LinkedHashMap<>();
        for (TypedColumn column : columns) {
            DataCell cell = row.getCell(column);
            if (cell != null) {
                fields.put(column.getName(), CharMatcher.BREAKING_WHITESPACE.removeFrom(cell.getValue()));
            } else {
                fields.put(column.getName(), "");
            }
        }
        writer.writeRow(fields);
    }

    @Override
    public void close() throws IOException {
        this.writer.close();
    }
    //endregion
}
